package com.spsyry.pay.conteoller;

import com.alibaba.fastjson.JSON;
import com.spsyry.api.OrderApi;
import com.spsyry.common.core.domain.R;
import com.spsyry.pay.constatant.RabbitmqConstant;
import com.spsyry.pay.domain.PaymentOrder;
import com.spsyry.pay.enums.PayOrderEnum;
import com.spsyry.pay.mapper.PaymentOrderMapper;
import com.spsyry.pay.order.CommUtil;
import com.spsyry.pay.order.Constants;
import com.spsyry.pay.order.XMLUtil;
import com.spsyry.pay.vo.OrderVo;
import com.spsyry.pay.vo.PaymentOrderVo;
import com.spsyry.pay.vo.mq.MqOrderVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import java.util.Map;

/**
 * @author: liuzhiping
 * @date: 2024/12/12 21:35
 **/
@RestController
@Slf4j
@CrossOrigin
@RequestMapping(value = "/pay")
public class WeixinPayNotifyController {

    @Autowired
    private PaymentOrderMapper paymentOrderMapper;


    /*@RequestMapping(value="weixin/notify",method= RequestMethod.POST, produces = {"application/xml; charset=UTF-8"})
    public void notifyFromWx(HttpServletRequest request, HttpServletResponse response) {
        log.info("==========>微信回到接口。。。。。白杨支付成功回调");
    }*/

    @PostMapping(value = "/weixin/notifyTest",consumes = MediaType.APPLICATION_JSON_VALUE)
    public R createOrder(@RequestBody PaymentOrderVo paymentOrderVo) throws Exception{

        log.info("weixinNotifyVo:{}",JSON.toJSONString(paymentOrderVo));

        if(paymentOrderVo.getReturnCode().equals("success")){
            //通过订单号修改状态的。
            int updateCount = this.paymentOrderMapper.updatePaymentOrderId(PaymentOrder.builder().orderNo(paymentOrderVo.getOrderNo()).orderStatus(PayOrderEnum.SUCCESS.getDescription()).build());

            log.info("updateCount:{}",updateCount);
            return R.ok();
        }else {
            return R.fail("fail");
        }

    }




    /**
     * 微信回调
     * value="weixin/notify"：接口的 “具体路径” 完整访问地址是 http://我们的服务器地址/pay/weixin/notify
     * method=RequestMethod.POST：只能用 “POST 请求” 访问
     * produces="application/xml; charset=UTF-8"：这个接口返回的数据格式是 XML
     * HttpServletRequest request：用来接收微信发过来的 “支付结果数据”
     * HttpServletResponse response：用来给微信返回 “我们已经收到并处理了通知” 的响应。
     * @return
     */

    @Autowired
    private OrderApi orderApi;
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @RequestMapping(value="weixin/notify",method= RequestMethod.POST, produces = {"application/xml; charset=UTF-8"})
    public void asyncNotifyFromWx(HttpServletRequest request, HttpServletResponse response) {
        String uuid = "2302a-1234567890";

        long start = System.currentTimeMillis();

        int retunCode = 0;

        String msg = "";

        // 用来拼接读取到的XML数据
        StringBuilder builder = new StringBuilder();
        BufferedReader reader = null;
        try {
            // 从请求中获取“数据读取工具”
            reader = request.getReader();
            String str = "";

            // 一行一行读微信发过来的XML数据，直到读完
            while((str = reader.readLine()) != null){
                builder.append(str);
            }

            // 打印日志：告诉我们“收到微信回调了，数据是xxx”
            log.info("====notify wx 微信回调2302a【开始】 uuid={},data={}",uuid,builder.toString());


            /***
             * <xml>
             * <appid><![CDATA[wxbbac76fb81c710c6]]></appid>
             * <bank_type><![CDATA[CFT]]></bank_type>
             * <cash_fee><![CDATA[1]]></cash_fee>
             * <fee_type><![CDATA[CNY]]></fee_type>
             * <is_subscribe><![CDATA[N]]></is_subscribe>
             * <mch_id><![CDATA[1548473611]]></mch_id>
             * <nonce_str><![CDATA[eed46ee215b849a7806012498c1b8056]]></nonce_str>
             * <openid><![CDATA[oZAf_jjxQKRJHv2BVHluoizFoUIM]]></openid>
             * <out_trade_no><![CDATA[order620191028161608XYTVSZGJEJ]]></out_trade_no>
             * <result_code><![CDATA[SUCCESS]]></result_code>
             * <return_code><![CDATA[SUCCESS]]></return_code>
             * <sign><![CDATA[DEDE8DC07012C69A18824A9523843F40]]></sign>
             * <time_end><![CDATA[20191028161652]]></time_end>
             * <total_fee>1</total_fee>
             * <trade_type><![CDATA[APP]]></trade_type>
             * <transaction_id><![CDATA[4200000409201910286163121037]]></transaction_id>
             * </xml>
             */
            /*ResultData resultData = this.notifyReceiveWxService.doNotify(uuid,builder.toString());*/

            // 调用XML工具类，把XML字符串转成Map
            Map<String,String> map = XMLUtil.doXMLParse(builder.toString());

            // 打印日志：告诉我们转换后的Map长什么样（方便排查）
            log.info("====notify wx2302a 微信结果【结束】 map={}",JSON.toJSONString(map));

            // 1. 从微信发的通知里拿到微信的签名（weixinSign）
            String weixinSign = map.get("sign");
            // 2. 我们自己用微信给的“API密钥”（Constants.API_KEY）和同样的算法（MD5）生成一个签名（selfSign）
            String selfSign = CommUtil.genSign(map, Constants.API_KEY,"MD5");

            /*if(!weixinSign.equals(selfSign)){
                //------返回
                PrintWriter out = null;
                try {
                    String returnCode = retunCode==200 ?"SUCCESS":"FAIL";
                    builder = new StringBuilder();
                    response.setContentType("text/xml;charset=utf-8");
                    out = response.getWriter();
                    builder.append("<xml>\n");
                    builder.append("  <return_code><![CDATA["+returnCode+"]]></return_code>\n");
                    builder.append("	<return_msg><![CDATA["+msg+"]]></return_msg>\n");
                    builder.append("</xml>\n");

                    log.info("=====返回数据 sb={}",builder.toString());
                    out.write(builder.toString());
                    out.flush();
                } catch (IOException e) {

                    log.error("=====notify->from->wx error("+uuid+"):"+e.getMessage(),e);
                }
                finally {
                    if(reader!=null) {
                        try {
                            reader.close();
                        } catch (IOException e) {
                            log.error(e.getMessage(),e);
                        }
                    }
                    if(out!=null) {
                        out.close();
                    }
                    log.info("=====notify->from->wx end("+uuid+"):"+(System.currentTimeMillis()-start));
                }
                return;
            }*/


            //3724200166688801688

            // 从Map里拿到关键数据：我们自己的订单号、微信返回的支付结果
            String orderNo = map.get("out_trade_no");
            log.info("----------123456 orderNo:{} ",orderNo);


            String resultCode = map.get("result_code");
            String returnCode = map.get("return_code");

            // 只有“通信成功”且“支付成功”，才处理订单
            if(resultCode.toUpperCase().equals("SUCCESS") && returnCode.toUpperCase().equals("SUCCESS")){


//                LambdaUpdateWrapper<PaymentOrder> lambdaUpdateWrapper = new LambdaUpdateWrapper();
//                lambdaUpdateWrapper.set(PaymentOrder::getStatus,2);
//                lambdaUpdateWrapper.eq(PaymentOrder::getOrderNo,orderNo);
//                int updateCount = this.paymentOrderMapper.update(null,lambdaUpdateWrapper);
                //log.info("订单状态修改成功 orderNo:{} updateCount:{}",orderNo,updateCount);
                MqOrderVo build = MqOrderVo.builder().orderId(orderNo).status(PayOrderEnum.ACCEPT.getDescription()).build();

                rabbitTemplate.convertAndSend(RabbitmqConstant.MQ_EXCHANGE_NAME,RabbitmqConstant.MQ_ROUTING_KEY,JSON.toJSONString(build));


                List<PaymentOrder> list = this.paymentOrderMapper.selectPaymentOrderList(PaymentOrder.builder().merchantOrderNo(orderNo).build());
//                //状态判断
//                if(list!=null&&list.size()>=1){
//                    PaymentOrder paymentOrder = list.get(0);
//                    //判断这个订单是不是已支付状态
//                    if (paymentOrder.getOrderStatus().intValue()!= PayOrderEnum.SUCCESS.getDescription()){
//                       //通过订单号修改状态的。
//                        //把微信的原始值保留到库
//                        int updateCount = this.paymentOrderMapper.updatePaymentOrder(PaymentOrder.builder().merchantOrderNo(orderNo).orderStatus(PayOrderEnum.REFUND.getDescription()).build());
//
//                        NotifyPay2OrderVo addCreateVo = new NotifyPay2OrderVo();
//                        addCreateVo.setOrderId(orderNo);
//                        addCreateVo.setStatus(2);
//                        this.orderApi.createOrder(addCreateVo);
//                    }
//
//                }
                //修改数据库的订单号为支付已成功；
            }

            //逻辑处理 TODO: 数据库操作 ？？？

            //回调订单系统 openfeign
            // 创建订单系统 0-1
            // 多库-多表
            // openfeign 进程直接的调用
            // 日志打印

            //微信通知了我，【我要通知订单系统】
            //订单系统提供一下接口,参数{订单号,支付状态}



            retunCode = 200;

            msg = "成功";
        } catch (Exception e) {
            msg ="回调处理失败";

        }
        //int i = 1/0;
        //------返回
        PrintWriter out = null;
        try {
            String returnCode = retunCode==200 ?"SUCCESS":"FAIL";
            builder = new StringBuilder();
            response.setContentType("text/xml;charset=utf-8");
            out = response.getWriter();
            builder.append("<xml>\n");
            builder.append("  <return_code><![CDATA["+returnCode+"]]></return_code>\n");
            builder.append("	<return_msg><![CDATA["+msg+"]]></return_msg>\n");
            builder.append("</xml>\n");

            log.info("=====返回数据 sb={}",builder.toString());
            out.write(builder.toString());
            out.flush();
        } catch (IOException e) {

            log.error("=====notify->from->wx error("+uuid+"):"+e.getMessage(),e);
        }
        finally {
            if(reader!=null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    log.error(e.getMessage(),e);
                }
            }
            if(out!=null) {
                out.close();
            }
            log.info("=====notify->from->wx end("+uuid+"):"+(System.currentTimeMillis()-start));
        }
    }
}
